public class Solution {
    private char[][] board;
    private String word;
    private boolean[][] visited;

    private boolean dfs(int x, int y, int i) {
        if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) return false;
        if (visited[x][y]) return false;
        if (board[x][y] != word.charAt(i)) return false;
        if (i == word.length() - 1) return true;
        visited[x][y] = true;
        boolean ret = dfs(x + 1, y, i + 1) || dfs(x, y + 1, i + 1) || dfs(x - 1, y, i + 1) || dfs(x, y - 1, i + 1);
        visited[x][y] = false;
        return ret;
    }

    public boolean exist(char[][] board, String word) {
        this.board = board;
        this.word = word;
        this.visited = new boolean[board.length][board[0].length];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (dfs(i, j, 0)) return true;
            }
        }
        return false;
    }
}